using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using MinoChat.Data.Entities;
using MinoChat.Data.Services.Interfaces;
using MinoChat.Messages;
using MinoChat.Provider.Services.Interfaces;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.AI;
using ChatMessage = MinoChat.Data.Entities.ChatMessage;
using AIChatMessage = Microsoft.Extensions.AI.ChatMessage;

namespace MinoChat.ViewModels.Pages;

public partial class ChatPageViewModel : ObservableObject
{
    private readonly ILogger<ChatPageViewModel> _logger;
    private readonly IChatDataService _chatDataService;
    private readonly IProviderService _providerService;
    private readonly IProviderConfigService _providerConfigService;
    private readonly ITitleSummaryService _titleSummaryService;

    [ObservableProperty]
    private ObservableCollection<ChatMessage> _chatMessages = new();
    [ObservableProperty]
    private ChatSession? _currentChatSession;

    [ObservableProperty]
    private string _userInput = string.Empty;

    [ObservableProperty]
    private bool _isProcessing = false;

    [ObservableProperty]
    private ObservableCollection<string> _loadedMcpTools = new();

    [ObservableProperty]
    private ObservableCollection<string> _loadedModels = new();

    [ObservableProperty]
    private string _selectedMcpTool = string.Empty;

    [ObservableProperty]
    private string _selectedModel = string.Empty;

    public ChatPageViewModel(ILogger<ChatPageViewModel> logger, IChatDataService chatDataService,
        IProviderService providerService, IProviderConfigService providerConfigService, ITitleSummaryService titleSummaryService)
    {
        _logger = logger;
        _chatDataService = chatDataService;
        _providerService = providerService;
        _providerConfigService = providerConfigService;
        _titleSummaryService = titleSummaryService;

        // 初始化配置并加载模型
        _ = InitializeProvidersAsync();

        // 无论是选中历史会话，还是新建会话，都会发送SessionChangedMessage消息，此处接收到消息保证正确加载对应message
        // 订阅会话切换消息
        WeakReferenceMessenger.Default.Register<SessionChangedMessage>(this, async (r, m) =>
        {
            await LoadSessionAsync(m.Value);
        });

        // 订阅标题变更消息 - 直接更新标题，不重新加载会话
        WeakReferenceMessenger.Default.Register<SessionTitleChangedMessage>(this, (r, m) =>
        {
            if (CurrentChatSession?.Id == m.Value.SessionId)
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    CurrentChatSession.Title = m.Value.Title;
                    CurrentChatSession.Model = m.Value.Model;
                    _logger.LogInformation("ChatPage已更新会话标题: {Title}", m.Value.Title);
                });
            }
        });

        // 订阅配置切换消息
        WeakReferenceMessenger.Default.Register<ProviderConfigChangedMessage>(this, async (r, m) =>
        {
            await InitializeProvidersAsync();
        });
    }

    private async Task InitializeProvidersAsync()
    {
        try
        {
            // 确保默认配置存在
            await _providerConfigService.EnsureDefaultConfigExistsAsync();

            // 加载当前配置
            var currentConfigName = _providerConfigService.GetCurrentConfigFileName();
            var config = await _providerConfigService.LoadConfigurationAsync(currentConfigName);

            if (config != null)
            {
                // 加载模型
                await _providerService.LoadModelsFromConfigAsync(config, currentConfigName);        
                // 更新模型列表
                LoadedModels.Clear();
                LoadedMcpTools.Clear(); // MCP Tools 暂时清空
                foreach (var model in _providerService.GetAvailableModels())
                {
                    LoadedModels.Add(model.DisplayName);
                }
                // 设置默认模型
                if (LoadedModels.Count > 0)
                {
                    SelectedModel = LoadedModels.FirstOrDefault() ?? string.Empty;
                }
                _logger.LogInformation("成功加载 {Count} 个模型", LoadedModels.Count);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "初始化Provider失败");
        }
    }
    // 根据SessionId从数据库加载会话和消息
    private async Task LoadSessionAsync(Guid sessionId)
    {
        try
        {
            // 防止重复加载同一会话
            if (CurrentChatSession?.Id == sessionId)
            {
                _logger.LogInformation("会话已加载，跳过重复加载: {SessionId}", sessionId);
                return;
            }

            // 从数据服务获取的会话ChatSession包含了的Messages本身就包含了所有消息
            var session = await _chatDataService.GetChatSessionByIdAsync(sessionId);
            if (session != null)
            {
                CurrentChatSession = session;
                ChatMessages.Clear();
                foreach (var message in session.Messages)
                {
                    ChatMessages.Add(message);
                }
                _logger.LogInformation("已加载会话: {Title}, 消息数: {Count}", session.Title, session.Messages.Count);
            }
            else
            {
                _logger.LogWarning("未找到会话: {SessionId}", sessionId);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "加载会话失败: {SessionId}", sessionId);
        }
    }

    [RelayCommand]
    private async Task SendMessage()
    {
        // 防抖：通过设置IsProcessing标志防止多次点击反复执行
        if (string.IsNullOrWhiteSpace(UserInput) || IsProcessing || CurrentChatSession == null)
            return;
        IsProcessing = true;

        // 创建AI消息占位符
        ChatMessage? aiResponse = null;

        try
        {
            // 创建用户消息
            var userMessage = new ChatMessage
            {
                Content = UserInput,
                IsUserMessage = true,
                Timestamp = DateTime.Now,
                SequenceNumber = CurrentChatSession.Messages.Count
            };

            // 添加message到UI集合和会话集合
            ChatMessages.Add(userMessage);
            CurrentChatSession.Messages.Add(userMessage);
            CurrentChatSession.LastMessageTime = DateTime.Now;
            // 保存用户消息
            await _chatDataService.SaveChatSessionAsync(CurrentChatSession);

            // 清空输入
            var userInputText = UserInput;
            UserInput = string.Empty;

            // 调用真实AI服务
            try
            {
                // 转换消息格式
                var aiMessages = ChatMessages.Select(m =>
                    m.IsUserMessage
                        ? new AIChatMessage(new ChatRole("user"), m.Content)
                        : new AIChatMessage(new ChatRole("assistant"), m.Content)
                ).ToList();

                // 找到选中模型的ID
                var models = _providerService.GetAvailableModels();
                var selectedModelConfig = models.FirstOrDefault(m => m.DisplayName == SelectedModel);

                if (selectedModelConfig == null)
                {
                    throw new Exception("未找到选中的模型配置");
                }

                // 创建AI回复消息占位符
                aiResponse = new ChatMessage
                {
                    Content = string.Empty,
                    IsUserMessage = false,
                    Timestamp = DateTime.Now,
                    ModelId = selectedModelConfig.ModelId,
                    SequenceNumber = CurrentChatSession.Messages.Count
                };

                // 添加到UI集合（立即显示空消息）
                ChatMessages.Add(aiResponse);
                CurrentChatSession.Messages.Add(aiResponse);

                // 使用流式API获取响应
                var fullResponse = string.Empty;
                await foreach (var chunk in _providerService.SendMessageStreamAsync(
                    selectedModelConfig.Id,
                    aiMessages,
                    CancellationToken.None
                ))
                {
                    fullResponse += chunk;
                    // 更新UI（触发属性变更通知）
                    aiResponse.Content = fullResponse;
                }

                CurrentChatSession.LastMessageTime = DateTime.Now;

                // 如果是第一次对话（第一条用户消息和第一条AI回复），生成标题并更新模型
                // 统计用户消息数量，如果只有1条，说明是第一次对话
                var userMessageCount = CurrentChatSession.Messages.Count(m => m.IsUserMessage);
                if (userMessageCount == 1)
                {
                    _logger.LogInformation("检测到首次对话，开始生成标题");
                    var title = await _titleSummaryService.GenerateTitleAsync(userInputText, fullResponse);
                    CurrentChatSession.Title = title;
                    _logger.LogInformation("标题生成成功: {Title}", title);

                    // 更新会话的模型ID为实际使用的模型
                    CurrentChatSession.Model = selectedModelConfig.ModelId;
                    _logger.LogInformation("更新会话模型: {Model}", selectedModelConfig.ModelId);

                    // 发送消息，同时传递标题和模型
                    WeakReferenceMessenger.Default.Send(new SessionTitleChangedMessage(
                        CurrentChatSession.Id, title, selectedModelConfig.ModelId));
                }
                // 如果会话的 Model 为空或是默认占位符，也更新为当前使用的模型（处理旧会话）
                else if (string.IsNullOrEmpty(CurrentChatSession.Model) || CurrentChatSession.Model == "Mino-Chat")
                {
                    CurrentChatSession.Model = selectedModelConfig.ModelId;
                    _logger.LogInformation("更新旧会话模型: {Model}", selectedModelConfig.ModelId);
                }

                // 保存AI回复
                await _chatDataService.SaveChatSessionAsync(CurrentChatSession);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "AI服务调用失败");

                // 如果AI消息已经添加，更新为错误消息
                if (aiResponse != null)
                {
                    aiResponse.Content = $"抱歉，AI服务调用失败：{ex.Message}\n\n请检查配置后重试。";
                }
                else
                {
                    // 添加错误消息
                    var errorMessage = new ChatMessage
                    {
                        Content = $"抱歉，AI服务调用失败：{ex.Message}\n\n请检查配置后重试。",
                        IsUserMessage = false,
                        Timestamp = DateTime.Now
                    };
                    ChatMessages.Add(errorMessage);
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送消息失败");
        }
        finally
        {
            IsProcessing = false;
        }
    }
    [RelayCommand]
    private void ClearChat()
    {
        ChatMessages.Clear();
        CurrentChatSession?.Messages.Clear();
    }

    /// <summary>
    /// 刷新会话标题 - 根据当前会话的前两条消息重新生成标题
    /// </summary>
    [RelayCommand]
    private async Task RefreshTitle()
    {
        if (CurrentChatSession == null || ChatMessages.Count < 2)
        {
            _logger.LogWarning("无法刷新标题：会话为空或消息少于2条");
            return;
        }

        try
        {
            // 获取第一条用户消息和第一条AI回复
            var firstUserMessage = ChatMessages.FirstOrDefault(m => m.IsUserMessage);
            var firstAiMessage = ChatMessages.FirstOrDefault(m => !m.IsUserMessage);

            if (firstUserMessage == null || firstAiMessage == null)
            {
                _logger.LogWarning("无法刷新标题：找不到用户消息或AI回复");
                return;
            }

            _logger.LogInformation("开始刷新标题，会话ID: {SessionId}", CurrentChatSession.Id);

            // 调用标题生成服务
            var newTitle = await _titleSummaryService.GenerateTitleAsync(
                firstUserMessage.Content,
                firstAiMessage.Content
            );

            _logger.LogInformation("标题生成成功: {Title}", newTitle);

            // 更新标题
            CurrentChatSession.Title = newTitle;
            await _chatDataService.SaveChatSessionAsync(CurrentChatSession);

            // 发送标题变更消息，同时传递模型ID
            WeakReferenceMessenger.Default.Send(new SessionTitleChangedMessage(
                CurrentChatSession.Id, newTitle, CurrentChatSession.Model));

            _logger.LogInformation("标题刷新完成");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "刷新标题失败");
        }
    }
}